package com.haha;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shenlinnan
 * @date 2025/7/27 15:13
 */
public class WoWGroupScanner extends JFrame {

    // 配置参数 - 根据您的游戏界面进行调整
    private static final int LINE_HEIGHT = 24;        // 每行角色高度(像素)
    private static final int TEXT_X = 250;            // 角色名称起始X坐标
    private static final int TEXT_Y_START = 150;      // 角色列表起始Y坐标
    private static final int MAX_LINES = 12;          // 最大扫描行数
    private static final int SCREEN_SCALE = 1;        // 屏幕缩放比例(Windows系统通常为100% = 1, 150% = 2)

    private JTextArea outputArea;
    private JLabel previewLabel;
    private JLabel helpLabel;
    private BufferedImage lastCapture;

    private static final String[] CLASS_COLORS = {
            "战士: #C79C6E",
            "圣骑士: #F58CBA",
            "猎人: #ABD473",
            "潜行者: #FFF569",
            "牧师: #FFFFFF",
            "死亡骑士: #C41F3B",
            "萨满祭司: #0070DE",
            "法师: #3FC7EB",
            "术士: #8788EE",
            "武僧: #00FF98",
            "德鲁伊: #FF7D0A",
            "恶魔猎手: #A330C9",
            "唤魔师: #33937F"
    };

    public WoWGroupScanner() {
        setTitle("魔兽世界组队列表扫描器");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 顶部面板
        JPanel headerPanel = new JPanel();
        headerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        headerPanel.setLayout(new BorderLayout());

        JLabel titleLabel = new JLabel("魔兽世界组队列表扫描工具");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        headerPanel.add(titleLabel, BorderLayout.NORTH);

        helpLabel = new JLabel("按 F11 键扫描当前游戏界面中的寻求组队列表");
        helpLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        headerPanel.add(helpLabel, BorderLayout.CENTER);

        // 预览面板
        JPanel previewPanel = new JPanel();
        previewLabel = new JLabel();
        previewLabel.setHorizontalAlignment(SwingConstants.CENTER);
        previewPanel.add(previewLabel);

        // 输出面板
        outputArea = new JTextArea();
        outputArea.setEditable(false);
        outputArea.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        outputArea.setBackground(new Color(30, 30, 30));
        outputArea.setForeground(Color.WHITE);
        JScrollPane scrollPane = new JScrollPane(outputArea);

        // 信息面板
        JPanel classColorsPanel = new JPanel();
        classColorsPanel.setLayout(new GridLayout(4, 4, 10, 5));
        for (String colorInfo : CLASS_COLORS) {
            JLabel label = new JLabel(colorInfo);
            label.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
            classColorsPanel.add(label);
        }

        // 添加面板到主窗口
        add(headerPanel, BorderLayout.NORTH);
        add(previewPanel, BorderLayout.CENTER);
        add(scrollPane, BorderLayout.SOUTH);
        add(classColorsPanel, BorderLayout.EAST);

        // 设置F11快捷键
        setupHotkey();
    }

    private void setupHotkey() {
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0), "scanAction");

        getRootPane().getActionMap().put("scanAction", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new Thread(WoWGroupScanner.this::scanGroupFinder).start();
            }
        });
    }

    private void scanGroupFinder() {
        try {
            outputArea.setText("");
            helpLabel.setText("扫描中...");

            // 截取屏幕
            Robot robot = new Robot();
            Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
            lastCapture = robot.createScreenCapture(screenRect);

            // 显示截图预览
            ImageIcon previewIcon = new ImageIcon(lastCapture.getScaledInstance(
                    200, 300, Image.SCALE_SMOOTH));
            previewLabel.setIcon(previewIcon);

            // 扫描角色信息
            List<CharacterInfo> characters = new ArrayList<>();
            int yPosition = TEXT_Y_START;

            for (int line = 0; line < MAX_LINES; line++) {
                CharacterInfo charInfo = extractCharacterInfo(lastCapture, yPosition);
                System.out.println();
                if (charInfo != null) {
                    characters.add(charInfo);
                }
                yPosition += LINE_HEIGHT;
            }

            // 显示结果
            outputArea.append("=== 寻求组队列表 ===\n");
            for (CharacterInfo character : characters) {
                String rgb = String.format("角色: %-15s | 颜色: RGB(%3d, %3d, %3d)",
                        character.name,
                        character.color.getRed(),
                        character.color.getGreen(),
                        character.color.getBlue());

                // 添加推测的职业信息
                String classGuess = guessClassFromColor(character.color);
                if (!classGuess.isEmpty()) {
                    rgb += " | 推测职业: " + classGuess;
                }

                outputArea.append(rgb + "\n");
            }

            if (characters.isEmpty()) {
                outputArea.append("未找到角色信息，请调整设置或确保组队列表可见\n");
            }

            helpLabel.setText("按 F11 键重新扫描");

        } catch (AWTException ex) {
            helpLabel.setText("初始化错误: " + ex.getMessage());
            ex.printStackTrace();
        }
    }

    private String guessClassFromColor(Color color) {
        if (color == null) return "";

        // 使用标准色差公式判断
        double[] distances = new double[CLASS_COLORS.length];
        for (int i = 0; i < CLASS_COLORS.length; i++) {
            String hex = CLASS_COLORS[i].split(":")[1].trim();
            Color classColor = Color.decode(hex);
            double distance = calculateColorDistance(color, classColor);
            distances[i] = distance;
        }

        // 找到最接近的颜色
        int minIndex = 0;
        double minDistance = distances[0];
        for (int i = 1; i < distances.length; i++) {
            if (distances[i] < minDistance) {
                minDistance = distances[i];
                minIndex = i;
            }
        }

        // 如果距离太远则不确定
        if (minDistance > 100) return "未知";

        return CLASS_COLORS[minIndex].split(":")[0].trim();
    }

    private double calculateColorDistance(Color c1, Color c2) {
        double rmean = (c1.getRed() + c2.getRed()) / 2.0;
        double r = c1.getRed() - c2.getRed();
        double g = c1.getGreen() - c2.getGreen();
        double b = c1.getBlue() - c2.getBlue();
        double weightR = 2 + rmean / 256.0;
        double weightG = 4.0;
        double weightB = 2 + (255 - rmean) / 256.0;
        return Math.sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
    }

    private CharacterInfo extractCharacterInfo(BufferedImage image, int y) {
        int startX = TEXT_X;
        int endX = startX;
        int lineEnd = image.getWidth() - 50;

        // 查找角色文本的开始位置
        while (startX < lineEnd) {
            if (!isTransparentOrBackground(image, startX, y)) {
                break;
            }
            startX++;
        }

        // 查找角色文本的结束位置
        endX = startX;
        boolean inText = false;
        int consecutiveBackground = 0;

        while (endX < lineEnd) {
            Color pixelColor = new Color(image.getRGB(endX, y), true);

            // 判断是否为文本像素
            if (!isTransparentOrBackground(image, endX, y)) {
                inText = true;
                consecutiveBackground = 0;
            } else if (inText) {
                consecutiveBackground++;
                if (consecutiveBackground > 5) { // 连续5个背景像素认为是文本结束
                    break;
                }
            }
            endX++;
        }

        if (endX - startX < 10) { // 过滤过短的文本
            return null;
        }

        // 创建包含角色文本区域的图像
        BufferedNameExtractor nameExtractor = new BufferedNameExtractor();
        nameExtractor.processImageRegion(image, startX, y, endX - startX, LINE_HEIGHT);

        // 获取主要颜色
        Color mainColor = getMainColorForText(image, startX, endX, y);

        return new CharacterInfo(nameExtractor.getRecognizedName(), mainColor);
    }

    private Color getMainColorForText(BufferedImage image, int startX, int endX, int y) {
        int redSum = 0, greenSum = 0, blueSum = 0;
        int pixelCount = 0;
        int centerY = y + LINE_HEIGHT / 2;

        for (int x = startX; x < endX; x++) {
            Color pixelColor = new Color(image.getRGB(x, centerY), true);

            // 忽略透明和深背景
            if (!isTransparentOrBackground(image, x, centerY)) {
                redSum += pixelColor.getRed();
                greenSum += pixelColor.getGreen();
                blueSum += pixelColor.getBlue();
                pixelCount++;
            }
        }

        if (pixelCount == 0) {
            return Color.BLACK;
        }

        return new Color(
                redSum / pixelCount,
                greenSum / pixelCount,
                blueSum / pixelCount
        );
    }

    private boolean isTransparentOrBackground(BufferedImage image, int x, int y) {
        if (x < 0 || y < 0 || x >= image.getWidth() || y >= image.getHeight()) {
            return true;
        }

        int rgb = image.getRGB(x, y);
        int alpha = (rgb >> 24) & 0xFF;
        int red = (rgb >> 16) & 0xFF;
        int green = (rgb >> 8) & 0xFF;
        int blue = rgb & 0xFF;

        // 检测透明度
        if (alpha < 100) {
            return true;
        }

        // 检测深色背景
        double brightness = 0.299 * red + 0.587 * green + 0.114 * blue;
        if (brightness < 30) { // 较暗的背景
            return true;
        }

        return false;
    }

    static class CharacterInfo {
        String name;
        Color color;

        public CharacterInfo(String name, Color color) {
            this.name = name;
            this.color = color;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            WoWGroupScanner scanner = new WoWGroupScanner();
            scanner.setVisible(true);

            // 确保窗口在Windows系统上有正确缩放
            if (System.getProperty("os.name").toLowerCase().contains("win")) {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}

class BufferedNameExtractor {
    private String recognizedName = "";

    public void processImageRegion(BufferedImage image, int startX, int startY, int width, int height) {
        // 简化版的"光学字符识别" - 实际实现可以使用Tesseract等OCR库

        // 这里使用基于颜色和位置的特征识别（仅作为示例）
        for (int x = startX; x < startX + width; x += 2) {
            for (int y = startY; y < startY + height; y += 2) {
                // 实际上更复杂的字符识别需要完整OCR实现
            }
        }

        // 由于OCR实现复杂，这里模拟结果
        char[] mockNames = {
                '勇', '敢', '的', '战', '士', '追', '风', '猎', '人',
                '影', '刃', '潜', '行', '者', '光', '明', '牧', '师',
                '冰', '霜', '法', '师', '邪', '恶', '术', '士', '自',
                '然', '德', '鲁', '伊', '神', '圣', '骑', '士', '死', '亡', '骑', '士'
        };

        StringBuilder sb = new StringBuilder();
        int nameLength = 3 + (int)(Math.random() * 4); // 3-6个字符的名字
        for (int i = 0; i < nameLength; i++) {
            sb.append(mockNames[(int)(Math.random() * mockNames.length)]);
        }

        recognizedName = sb.toString();
    }

    public String getRecognizedName() {
        return recognizedName;
    }

}
